<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  <title>go语言基础知识 | haijd</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  
  <meta name="keywords" content="Golang入门" />
  
  
  
  
  <meta name="description" content="基础知识 每个go程序都是由package定义的。package必须在源文件的第一行。 每个可执行程序必须有且只有一个main包，main包里面必须有main函数。  12345package main// todofunc main()&amp;#123;    //TODO&amp;#125;">
<meta name="keywords" content="Golang入门">
<meta property="og:type" content="article">
<meta property="og:title" content="Go语言基础知识">
<meta property="og:url" content="http://www.hais2.com/2017/08/11/Go语言基础知识/index.html">
<meta property="og:site_name" content="haijd">
<meta property="og:description" content="基础知识 每个go程序都是由package定义的。package必须在源文件的第一行。 每个可执行程序必须有且只有一个main包，main包里面必须有main函数。  12345package main// todofunc main()&amp;#123;    //TODO&amp;#125;">
<meta property="og:locale" content="default">
<meta property="og:image" content="http://ww1.sinaimg.cn/large/c55a7aeely1ficnszlhh9j20go098jrl.jpg">
<meta property="og:updated_time" content="2017-09-05T14:47:39.000Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Go语言基础知识">
<meta name="twitter:description" content="基础知识 每个go程序都是由package定义的。package必须在源文件的第一行。 每个可执行程序必须有且只有一个main包，main包里面必须有main函数。  12345package main// todofunc main()&amp;#123;    //TODO&amp;#125;">
<meta name="twitter:image" content="http://ww1.sinaimg.cn/large/c55a7aeely1ficnszlhh9j20go098jrl.jpg">
  
    <link rel="alternate" href="/atom.xml" title="haijd" type="application/atom+xml">
  
  <link rel="icon" href="/css/images/favicon.ico">
  
    <link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  
  <link href="https://fonts.googleapis.com/css?family=Open+Sans|Montserrat:700" rel="stylesheet" type="text/css">
  <link href="https://fonts.googleapis.com/css?family=Roboto:400,300,300italic,400italic" rel="stylesheet" type="text/css">
  <link href="//cdn.bootcss.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet">
  <style type="text/css">
    @font-face{font-family:futura-pt;src:url(https://use.typekit.net/af/9749f0/00000000000000000001008f/27/l?subset_id=2&fvd=n5) format("woff2");font-weight:500;font-style:normal;}
    @font-face{font-family:futura-pt;src:url(https://use.typekit.net/af/90cf9f/000000000000000000010091/27/l?subset_id=2&fvd=n7) format("woff2");font-weight:500;font-style:normal;}
    @font-face{font-family:futura-pt;src:url(https://use.typekit.net/af/8a5494/000000000000000000013365/27/l?subset_id=2&fvd=n4) format("woff2");font-weight:lighter;font-style:normal;}
    @font-face{font-family:futura-pt;src:url(https://use.typekit.net/af/d337d8/000000000000000000010095/27/l?subset_id=2&fvd=i4) format("woff2");font-weight:400;font-style:italic;}</style>
    
  <link rel="stylesheet" id="athemes-headings-fonts-css" href="//fonts.googleapis.com/css?family=Yanone+Kaffeesatz%3A200%2C300%2C400%2C700&amp;ver=4.6.1" type="text/css" media="all">
  <link rel="stylesheet" href="/css/style.css">

  <script src="/js/jquery-3.1.1.min.js"></script>

  <!-- Bootstrap core CSS -->
  <link rel="stylesheet" href="/css/bootstrap.css" >
  <link rel="stylesheet" href="/css/hiero.css" >
  <link rel="stylesheet" href="/css/glyphs.css" >
  
    <link rel="stylesheet" href="/css/vdonate.css" >
  

</head>

<script>
var themeMenus = {};

  themeMenus["/"] = "Home"; 

  themeMenus["/archives"] = "Archives"; 

  themeMenus["/categories"] = "Categories"; 

  themeMenus["/tags"] = "Tags"; 

  themeMenus["/about"] = "About"; 

</script>


  <body data-spy="scroll" data-target="#toc" data-offset="50">


  <header id="allheader" class="site-header" role="banner">
  <div class="clearfix container">
      <div class="site-branding">

          <h1 class="site-title">
            
              <a href="/" title="haijd" rel="home"> haijd </a>
            
          </h1>

          
            <div class="site-description">Stay Hungry,Stay Foolish</div>
          
            
          <nav id="main-navigation" class="main-navigation" role="navigation">
            <a class="nav-open">Menu</a>
            <a class="nav-close">Close</a>
            <div class="clearfix sf-menu">

              <ul id="main-nav" class="nmenu sf-js-enabled">
                    
                      <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-home menu-item-1663"> <a class="" href="/">Home</a> </li>
                    
                      <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-home menu-item-1663"> <a class="" href="/archives">Archives</a> </li>
                    
                      <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-home menu-item-1663"> <a class="" href="/categories">Categories</a> </li>
                    
                      <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-home menu-item-1663"> <a class="" href="/tags">Tags</a> </li>
                    
                      <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-home menu-item-1663"> <a class="" href="/about">About</a> </li>
                    
              </ul>
            </div>
          </nav>


      </div>
  </div>
</header>




  <div id="container">
    <div id="wrap">
            
      <div id="content" class="outer">
        
          <section id="main" style="float:none;"><article id="post-Go语言基础知识" style="width: 66%; float:left;" class="article article-type-post" itemscope itemprop="blogPost" >
  <div id="articleInner" class="clearfix post-1016 post type-post status-publish format-standard has-post-thumbnail hentry category-template-2 category-uncategorized tag-codex tag-edge-case tag-featured-image tag-image tag-template">
    
<div class="article-gallery">
  <div class="article-gallery-photos">
    
      <a class="article-gallery-img fancybox" href="http://ww1.sinaimg.cn/large/c55a7aeely1ficnszlhh9j20go098jrl.jpg" rel="gallery_cjie4nagy003o3swa5pkwa92i">
        <img src="http://ww1.sinaimg.cn/large/c55a7aeely1ficnszlhh9j20go098jrl.jpg" itemprop="image">
      </a>
    
  </div>
</div>

    
      <header class="article-header">
        
  
    <h1 class="thumb" class="article-title" itemprop="name">
      Go语言基础知识
    </h1>
  

      </header>
    
    <div class="article-meta">
      
	Posted on <a href="/2017/08/11/Go语言基础知识/" class="article-date">
	  <time datetime="2017-08-11T13:53:08.000Z" itemprop="datePublished">August 11, 2017</time>
	</a>

      
	<span id="busuanzi_container_page_pv">
	  本文总阅读量<span id="busuanzi_value_page_pv"></span>次
	</span>

    </div>
    <div class="article-entry" itemprop="articleBody">
      
        <h1 id="基础知识"><a href="#基础知识" class="headerlink" title="基础知识"></a>基础知识</h1><ul>
<li>每个go程序都是由<code>package</code>定义的。<code>package</code>必须在源文件的第一行。</li>
<li>每个可执行程序必须有且只有一个main包，main包里面必须有main函数。</li>
</ul>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"><span class="comment">// todo</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="comment">//TODO</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<a id="more"></a>
<ul>
<li><p>import</p>
<ul>
<li><p>多个包可以一个一个import：</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="string">"fmt"</span></span><br><span class="line"><span class="keyword">import</span> <span class="string">"os"</span></span><br><span class="line"><span class="keyword">import</span> <span class="string">"log"</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>也可以简化：</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> (</span><br><span class="line">    <span class="string">"fmt"</span></span><br><span class="line">    <span class="string">"os"</span></span><br><span class="line">    <span class="string">"log"</span></span><br><span class="line">    )</span><br><span class="line"><span class="comment">//调用</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    fmt.Println(<span class="string">"hello world"</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>导入的包没有调用里面的函数等，就会导致编译失败。</p>
</li>
<li><p>可以设置别名：</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> env <span class="string">"fmt"</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//调用</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    env.Println(<span class="string">"Hello world"</span>)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>或者可以直接省略调用：使用“<code>.</code>”代替别名，调用包函数的时候就不需要使用包名了(但是不推荐这样做)</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> . <span class="string">"fmt"</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">Println(<span class="string">"hello world"</span>)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>省略调用和别名不能同时使用</p>
</li>
<li>可见性规则：使用大小写来决定是<code>private</code>或者<code>public</code><ul>
<li>大写就是表示<code>public</code>，表示在包的外部可以调用</li>
<li>小写就是表示<code>private</code>，表示只能在包内部被调用</li>
</ul>
</li>
</ul>
</li>
</ul>
<h1 id="类型与变量"><a href="#类型与变量" class="headerlink" title="类型与变量"></a>类型与变量</h1><h2 id="基本类型"><a href="#基本类型" class="headerlink" title="基本类型"></a>基本类型</h2><ul>
<li>布尔类型：<code>bool</code><ul>
<li>长度：1字节</li>
<li>取值范围：true、false</li>
<li>不能使用c#等其他语言中的0、1来代表</li>
</ul>
</li>
<li>整型：<code>int</code>/<code>uint</code><ul>
<li>根据程序运行平台分为32/64位</li>
<li>int类型必须是整数，带小数的必须申明为float类型</li>
</ul>
</li>
<li>字节型：<code>byte</code>/<code>uint8</code></li>
<li>复数：</li>
<li>值类型：<ul>
<li><code>array</code>、<code>struct</code>、<code>string</code></li>
</ul>
</li>
<li>引用类型：<ul>
<li><code>slice</code>(切片)、<code>map</code>(哈希)、<code>chan</code>(通道,并发编程必不可少)</li>
</ul>
</li>
<li>接口类型：<code>interface</code></li>
<li>函数类型：<code>func</code></li>
</ul>
<h2 id="类型默认值"><a href="#类型默认值" class="headerlink" title="类型默认值"></a>类型默认值</h2><ul>
<li>值类型默认值为0</li>
<li>bool默认为false</li>
<li>string默认为空字符串</li>
</ul>
<h3 id="类型的别名"><a href="#类型的别名" class="headerlink" title="类型的别名"></a>类型的别名</h3><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line">    <span class="string">"fmt</span></span><br><span class="line"><span class="string">)</span></span><br><span class="line"><span class="string">//给类型起个别名</span></span><br><span class="line"><span class="string">type(</span></span><br><span class="line"><span class="string">    byte int8</span></span><br><span class="line"><span class="string">    rune int32</span></span><br><span class="line"><span class="string">    字符串 string</span></span><br><span class="line"><span class="string">)</span></span><br><span class="line"><span class="string">func main()&#123;</span></span><br><span class="line"><span class="string">    //使用别名“字符串”代替“string”申明变量</span></span><br><span class="line"><span class="string">    var str 字符串</span></span><br><span class="line"><span class="string">    str="</span>我是文本字符串<span class="string">"</span></span><br><span class="line"><span class="string">    fmt.Println(b);</span></span><br><span class="line"><span class="string">&#125;</span></span><br></pre></td></tr></table></figure>
<h2 id="变量的声明与赋值"><a href="#变量的声明与赋值" class="headerlink" title="变量的声明与赋值"></a>变量的声明与赋值</h2><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//申明一个int类型的变量a,未赋值，默认值为0</span></span><br><span class="line"><span class="keyword">var</span> a <span class="keyword">int</span> </span><br><span class="line"><span class="comment">//给变量a赋值  </span></span><br><span class="line">a = <span class="number">10</span>        </span><br><span class="line"><span class="comment">//申明变量的同时赋值</span></span><br><span class="line"><span class="keyword">var</span> b <span class="keyword">int</span> = <span class="number">10</span>    </span><br><span class="line"><span class="comment">//省略变量的类型，由编译器去根据值推断</span></span><br><span class="line"><span class="keyword">var</span> c = <span class="string">"hello"</span>   </span><br><span class="line"><span class="comment">//申明赋值简写形式(方法体内使用)</span></span><br><span class="line">d := <span class="number">111</span></span><br></pre></td></tr></table></figure>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//申明多个相同类型的变量</span></span><br><span class="line"><span class="keyword">var</span> a,b,c <span class="keyword">int</span></span><br><span class="line"><span class="comment">//申明的同时赋值</span></span><br><span class="line"><span class="keyword">var</span> a,b,c <span class="keyword">int</span> = <span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span></span><br><span class="line"><span class="comment">//省略类型</span></span><br><span class="line"><span class="keyword">var</span> a,b,c = <span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span></span><br><span class="line"><span class="comment">//简写形式</span></span><br><span class="line">a,b,c := <span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span></span><br></pre></td></tr></table></figure>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//使用“_”忽略其中一个参数(忽略了2这个值)</span></span><br><span class="line"><span class="keyword">var</span> a,_,c = <span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span></span><br><span class="line"><span class="comment">// 用在返回多个值的时候，忽略其中一个参数值</span></span><br></pre></td></tr></table></figure>
<h2 id="变量的类型转换"><a href="#变量的类型转换" class="headerlink" title="变量的类型转换"></a>变量的类型转换</h2><ul>
<li>Go语言中所有的类型转换必须是显示声明的强制转换</li>
<li>只能转换两种互相兼容的类型:例如int和float之间可以转换，但是int和bool之间转换会发生编译错误</li>
</ul>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a float = <span class="number">1.1</span></span><br><span class="line"><span class="keyword">var</span> b <span class="keyword">int</span> = <span class="keyword">int</span>(a)</span><br><span class="line"></span><br><span class="line"><span class="comment">//错误的转换</span></span><br><span class="line"><span class="keyword">var</span> a <span class="keyword">int</span> = <span class="number">0</span> </span><br><span class="line"><span class="keyword">var</span> b <span class="keyword">bool</span> = <span class="keyword">int</span>(a)</span><br></pre></td></tr></table></figure>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//int string</span></span><br><span class="line"><span class="keyword">var</span> a <span class="keyword">int</span> = <span class="number">65</span> </span><br><span class="line">b := <span class="keyword">string</span>(a)</span><br><span class="line">fmt.Println(b)</span><br><span class="line"></span><br><span class="line"><span class="comment">//输出一个"A"，将int类型直接转string的时候，编译器会认为将要进行转换的是计算机存储的字符代码，数字65代表的是字母A，所以就会输出A</span></span><br></pre></td></tr></table></figure>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//可以使用一个内置包进行int、string的转换</span></span><br><span class="line"><span class="keyword">package</span> main</span><br><span class="line"><span class="keyword">import</span>(</span><br><span class="line">    <span class="string">"fmt"</span></span><br><span class="line">    <span class="string">"strconv"</span></span><br><span class="line">)</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="keyword">var</span> a <span class="keyword">int</span> = <span class="number">65</span> </span><br><span class="line">    b := strconv.Itoa(a)  <span class="comment">//int转string</span></span><br><span class="line">    a = strconv.Atoi(b)   <span class="comment">//string转int</span></span><br><span class="line">    fmt.Println(b)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//输出的就是65</span></span><br></pre></td></tr></table></figure>
<h2 id="常量的定义"><a href="#常量的定义" class="headerlink" title="常量的定义"></a>常量的定义</h2><ul>
<li>常量的定义推荐使用全部大写字母声明</li>
<li>如果常量不想被外部调用，那就首字母需要是小写或者下划线</li>
<li>常量如果使用函数作为值，那么必须是一个内置函数</li>
<li>常量赋值必须是一个常量</li>
<li>同时声明多个常量，第一个常量必须赋默认值</li>
<li><p>申明多个常量，没有赋初始值的会默认取上一行的值</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> (</span><br><span class="line">    a = <span class="number">1</span></span><br><span class="line">    b</span><br><span class="line">    c</span><br><span class="line">)</span><br><span class="line"><span class="comment">// b和c就会默认取a的值，都等于1</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>可以使用常量实现枚举效果</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> (</span><br><span class="line">    a = <span class="string">"A"</span></span><br><span class="line">    b</span><br><span class="line">    c = <span class="literal">iota</span></span><br><span class="line">    d</span><br><span class="line">)</span><br><span class="line"><span class="comment">// 上面的声明中，a和b的值都是“A”,遵循没有赋值取上一行的值</span></span><br><span class="line"><span class="comment">// c 使用了一个iota，iota表示常量的计数器，从0开始一次递增1，所以c的值就是3</span></span><br></pre></td></tr></table></figure>
</li>
</ul>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> (</span><br><span class="line">    a = <span class="literal">iota</span></span><br><span class="line">    b,</span><br><span class="line">    c</span><br><span class="line">)</span><br><span class="line"><span class="comment">//作为声明的第一个常量不能省略赋值(要么是其他值，要么就是iota)</span></span><br></pre></td></tr></table></figure>
<h2 id="运算符"><a href="#运算符" class="headerlink" title="运算符"></a>运算符</h2><h2 id="控制语句"><a href="#控制语句" class="headerlink" title="控制语句"></a>控制语句</h2><ul>
<li><p>控制语句条件没有括号</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> a &gt; <span class="number">1</span> &#123;</span><br><span class="line">    <span class="comment">//TODO</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>可以在控制语句中声明变量并使用，但是作用域只在控制语句内</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    a := <span class="number">10</span></span><br><span class="line">    <span class="keyword">if</span> a := <span class="number">1</span>; a &gt; <span class="number">0</span> &#123;</span><br><span class="line">        fmt.Println(a)    <span class="comment">//输出的是1</span></span><br><span class="line">    &#125;</span><br><span class="line">    fmt.Println(a)        <span class="comment">//输出的是10</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h3 id="循环"><a href="#循环" class="headerlink" title="循环"></a>循环</h3><ul>
<li>Go语言中只有一个<code>for</code>循环关键字，像c#中除了<code>for</code>还有<code>foreach</code>、<code>while</code>关键字</li>
<li><p>Go语言中的<code>for</code>支持3种形式</p>
<ul>
<li><p>无限循环</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">mian</span><span class="params">()</span></span>&#123;</span><br><span class="line">    a := <span class="number">1</span></span><br><span class="line">    <span class="keyword">for</span> &#123;</span><br><span class="line">        a++</span><br><span class="line">        <span class="keyword">if</span> a &gt; <span class="number">3</span> &#123;</span><br><span class="line">            <span class="keyword">break</span>   <span class="comment">//必须要有一个条件控制，否则就进入无限循环状态</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>自带条件表达式</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span> <span class="params">()</span></span>&#123;</span><br><span class="line">    a := <span class="number">1</span></span><br><span class="line">    <span class="keyword">for</span> a &lt; <span class="number">10</span> &#123;</span><br><span class="line">        <span class="comment">//TODO</span></span><br><span class="line">        a++</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>正常循环语句</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; <span class="number">10</span>; i++&#123;</span><br><span class="line">        <span class="comment">//TODO</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
</li>
</ul>
<h3 id="switch"><a href="#switch" class="headerlink" title="switch"></a>switch</h3><ul>
<li><p>不需要写关键字<code>break</code>,符合条件就会自动终止switch</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    a := <span class="number">1</span></span><br><span class="line">    <span class="keyword">switch</span> a &#123;</span><br><span class="line">        <span class="keyword">case</span> <span class="number">0</span>:</span><br><span class="line">            fmt.Println(<span class="string">"a=0"</span>)</span><br><span class="line">        <span class="keyword">case</span> <span class="number">1</span>:</span><br><span class="line">            fmt.Println(<span class="string">"a=1"</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>如果符合后需要继续下一个<code>case</code>，那么就需要显示的使用<code>fallthrough</code>关键字</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    a := <span class="number">1</span></span><br><span class="line">    <span class="keyword">switch</span> &#123;</span><br><span class="line">        <span class="keyword">case</span> a &gt; <span class="number">0</span>:</span><br><span class="line">            fmt.Println(<span class="string">"a&gt;0"</span>)</span><br><span class="line">            <span class="keyword">fallthrough</span></span><br><span class="line">        <span class="keyword">case</span> a &lt; <span class="number">0</span>:</span><br><span class="line">            fmt.Println(<span class="string">"a&lt;0"</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>支持初始化一个表达式，这时表达式需要以封号结尾</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span> <span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="keyword">switch</span> a := <span class="number">1</span>;&#123;</span><br><span class="line">        <span class="keyword">case</span> a &gt; <span class="number">0</span>:</span><br><span class="line">            fmt.Println(<span class="string">"a&gt;0"</span>)</span><br><span class="line">            <span class="keyword">fallthrough</span></span><br><span class="line">        <span class="keyword">case</span> a &lt; <span class="number">0</span>:</span><br><span class="line">            fmt.Println(<span class="string">"a&lt;0"</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h2 id="Array"><a href="#Array" class="headerlink" title="Array"></a>Array</h2><ul>
<li><p>数组的声明</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    a := [<span class="number">2</span>]<span class="keyword">int</span>  <span class="comment">//数组必须要声明长度</span></span><br><span class="line">    b := [<span class="number">1</span>]<span class="keyword">int</span>  <span class="comment">//长度相同的两个数组，尽管元素类型一样，但是是属于两个不同的类型</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">//给数组赋值，在下面有两个元素的int数组中，值赋值了一个1，那么就会认为1是第一个元素的值，那么第二个元素就是int类型的默认值0</span></span><br><span class="line">    c := [<span class="number">2</span>]<span class="keyword">int</span>&#123;<span class="number">1</span>&#125;     <span class="comment">//output:[1,0]</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">//如果想给指定的元素赋值，那么就要使用索引形式</span></span><br><span class="line">    d := [<span class="number">5</span>]<span class="keyword">int</span>&#123;<span class="number">4</span>: <span class="number">1</span>&#125;  <span class="comment">//表示给索引为4也就是最后一个元素赋值1，其他的元素为int类型默认值</span></span><br><span class="line">    <span class="comment">//上面的语句输出[0,0,0,0,1]</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>可以不指定数组的长度</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    a := [...]<span class="keyword">int</span>&#123;<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>&#125;  <span class="comment">//使用3个点代替长度，编译器会自动帮我们计算</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">//也可以实现上面例子中的指定索引赋值</span></span><br><span class="line">    b := [...]<span class="keyword">int</span>&#123;<span class="number">19</span>: <span class="number">1</span>&#125;    <span class="comment">//这个数组的长度就是20，最后一个元素值为1，其他元素为0</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>数组在Go语言中为值类型(c#中是作为引用类型的)</p>
</li>
<li><p>可以对单个元素的值进行操作</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    a := [<span class="number">10</span>]<span class="keyword">int</span>&#123;&#125;</span><br><span class="line">    a[<span class="number">2</span>]=<span class="number">2</span>   <span class="comment">//对数组索引为2(第三个元素)进行赋值操作</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>可以定义使用多维数组</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    a := [<span class="number">2</span>][<span class="number">3</span>]<span class="keyword">int</span> &#123;</span><br><span class="line">        &#123;<span class="number">2</span>: <span class="number">1</span>&#125;,</span><br><span class="line">        &#123;<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>&#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>冒泡排序</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    a := [...]<span class="keyword">int</span>&#123;<span class="number">3</span>,<span class="number">6</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">8</span>&#125;</span><br><span class="line"></span><br><span class="line">    num := <span class="built_in">len</span>(a)  <span class="comment">//获取数组长度</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>;i &lt; num; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := i + <span class="number">1</span>; j &lt; num; j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> a[i] &lt; a[j]&#123;</span><br><span class="line">                temp := a[i]</span><br><span class="line">                a[i] = a[j]</span><br><span class="line">                a[j] = temp</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h2 id="切片Slice"><a href="#切片Slice" class="headerlink" title="切片Slice"></a>切片Slice</h2><ul>
<li>Slice本身不是数组，它只是指向一个数组的底层地址</li>
<li>因为指向的是的内存地址，所以Slice是引用类型</li>
<li><p>Slice可以从一个数组获取生成</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    a := [<span class="number">5</span>]<span class="keyword">int</span>&#123;<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>&#125;   </span><br><span class="line">    <span class="comment">//a1 ：= []int      //一个没有明确的长度的数组，就是Slice</span></span><br><span class="line">    s1 := a[<span class="number">2</span>]          <span class="comment">//s1现在指向数组a的索引为2的元素值为3</span></span><br><span class="line">    s2 := a[<span class="number">2</span>:<span class="number">5</span>]        <span class="comment">//s2现在指向数组a中的索引2开始的元素，一直到第5个元素(注意这里冒号后面的5不再是索引，而是第几个元素)，所以值为：345</span></span><br><span class="line">    s3 := a[<span class="number">2</span>:]         <span class="comment">//跟s2一样，冒号后面没有，表示取到最后。</span></span><br><span class="line">    s4 := a[:<span class="number">3</span>]         <span class="comment">//表示从索引0开始，取到第三个元素</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>Slice也可以使用函数<code>make([]T,len,cap)</code>进行创建</p>
<ul>
<li><code>[]T</code>：表示创建一个Slice(也就是不指定长度的数组)</li>
<li><code>len</code>：长度，表示这个Slice里面包含多少个元素</li>
<li><code>cap</code>：容量，因为Slice是长度可变的，为了不浪费空间，可以指定一个大致的容量，让内存取分配指定容量的连续内存空间。当实际存储的长度大于容量是，会自动的对容量进行乘2操作，并重新寻找一块新容量大小的连续内存空间。所以在开始应该对容量有一个大致的设定，避免频繁重新创建，带来的性能损耗。</li>
<li><code>cap</code>可以省略不写，如果<code>cap</code>省略掉，那么默认就和<code>len</code>相同<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="comment">//make函数的参数</span></span><br><span class="line">    s := <span class="built_in">make</span>([]<span class="keyword">int</span>,<span class="number">5</span>,<span class="number">10</span>)</span><br><span class="line">    fmt.Println(<span class="built_in">len</span>(s),<span class="built_in">cap</span>(s))   <span class="comment">//输出5，10</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
</li>
<li><p>Slice指向的是一个数组的内存地址，并不是一个独立的数组<br><img src="http://ww1.sinaimg.cn/large/c55a7aeely1figzlm0oafj20lm0d5abl.jpg" alt=""></p>
<ul>
<li>从图中可以看到，Slice_a 只包含三个元素，实际容量是包含了Array_ori这个数组的c元素开始到最后。</li>
<li>Slice_a根据内存寻址，可以找到从c开始到Array_ori这个数组结尾的所有元素，但是Slice_a本身只包含了c,d,e三个元素，这也说明了Slice指向的是一个底层数组的引用地址。</li>
<li>例如:<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Slice_a[<span class="number">2</span>]    <span class="comment">//得到“e”</span></span><br><span class="line">Slice_a[<span class="number">4</span>]    <span class="comment">//得到“g”</span></span><br></pre></td></tr></table></figure>
</li>
</ul>
</li>
<li><p>Reslice</p>
<ul>
<li><p>从一个Slice取一个新的Slice</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    a := [] <span class="keyword">int</span>&#123;<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>&#125;</span><br><span class="line">    s1 := a[<span class="number">2</span>:<span class="number">5</span>]     <span class="comment">//[3,4,5]</span></span><br><span class="line">    <span class="comment">//s2要取3,4元素</span></span><br><span class="line">    s2 := a[<span class="number">2</span>:<span class="number">4</span>]     <span class="comment">//可以从元素组中取</span></span><br><span class="line">    <span class="comment">//也可以从s1中取，因为s1已经包含3,4这两个元素了</span></span><br><span class="line">    s2 := s1[<span class="number">0</span>:<span class="number">2</span>]    <span class="comment">//取s1索引0开始到第二个元素就是3，4</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>Reslice索引不可以超越被Slice的切片的容量<code>cap()</code>的值，超过之后会引发编译错误，上面的例子中<code>s2</code>取值如果这么写就是错误的：<code>s2 := s1[3:6]</code>，索引3已经超过<code>s1</code>的最大容量(<code>s1</code>的最大容量是a数组从3开始到结尾的大小，结合上面的说明理解)</p>
</li>
</ul>
</li>
<li><p>Append </p>
<ul>
<li>可以在Slice的结尾追加元素</li>
<li><p>可以把一个Slice追加到另一个Slice的尾部</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    s := <span class="built_in">make</span>([]<span class="keyword">int</span>,<span class="number">3</span>,<span class="number">5</span>)   <span class="comment">//长度为3，容量为5的slice</span></span><br><span class="line">    s = <span class="built_in">append</span>(s,<span class="number">1</span>,<span class="number">2</span>)      <span class="comment">//把1，2两个元素追加到s的尾部，得到[0,0,0,1,2]</span></span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>如果最终追加后的长度没有超过slice的容量，那么返回的还是原来的那个slice，如果超过了，那么就会创建一个新的容量的内存空间，把数值复制到新的地址，然后返回的就是新的slice。</p>
<ul>
<li><p>追加后的slice没有超过原slice的容量</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    s := <span class="built_in">make</span>([]<span class="keyword">int</span>,<span class="number">5</span>,<span class="number">10</span>)</span><br><span class="line">    s = <span class="built_in">append</span>(s,<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>)        <span class="comment">//追加3个元素，总元素为8，没有超过s的容量10，那么新赋值的s，指向的内存地址还是原先s的地址</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>追加后的slice超过了远slice的容量</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    s := <span class="built_in">make</span>([]<span class="keyword">int</span>,<span class="number">5</span>,<span class="number">10</span>)</span><br><span class="line">    s = <span class="built_in">append</span>(s,<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>)    <span class="comment">//追加了6个元素，超过了原来s的最大容量10，那么就会创建一个新内存空间(大小为容量乘2)，将新的s复制进去，所以现在这个s指向的其实是一个新的内存地址了</span></span><br><span class="line">    s1 = s                      <span class="comment">//s1指向的还是原先s的内存地址                 </span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
</li>
</ul>
</li>
<li><p>Copy</p>
<ul>
<li><p>将一个slice拷贝到另一个slice中</p>
<ul>
<li><code>copy(拷贝到的slice,被拷贝的slice)</code></li>
<li><p>将长度大的slice拷贝到长度小的slice中</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    s1 := []<span class="keyword">int</span>&#123;<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>&#125;</span><br><span class="line">    s2 := []<span class="keyword">int</span>&#123;<span class="number">7</span>,<span class="number">8</span>,<span class="number">9</span>&#125;</span><br><span class="line">    <span class="built_in">copy</span>(s2,s1)       <span class="comment">//表示将s1拷贝到s2中，由于s1的长度为6，s2的长度为3，那么拷贝后s2就变成了[1,2,3]，因为s2的容量只有3，所以就把s1的前三个默认拷贝到s2中去了</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>将长度小的slice拷贝到长度大的slice中</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    s1 := []<span class="keyword">int</span>&#123;<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,&#125;</span><br><span class="line">    s2 := []<span class="keyword">int</span>&#123;<span class="number">7</span>,<span class="number">8</span>,<span class="number">9</span>&#125;</span><br><span class="line">    <span class="built_in">copy</span>(s1,s2)      <span class="comment">//将s2的元素拷贝到s1当中去，拷贝后的s1变成[7,8,9,3,4,5]</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
</li>
</ul>
</li>
<li><p>循环slice</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="comment">//i取的是slice中元素的索引，v取的是slice中的每一个值</span></span><br><span class="line">    <span class="keyword">for</span> i,v:=<span class="keyword">range</span> slice&#123;</span><br><span class="line">        <span class="comment">//直接给v这样赋值，是没有办法改变slice中v的值的，因为这里v获取的只是一个引用地址</span></span><br><span class="line">        v = <span class="string">"hello"</span></span><br><span class="line">        <span class="comment">//想要赋值，可以使用</span></span><br><span class="line">        slice[i] = <span class="string">"hello"</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h2 id="map"><a href="#map" class="headerlink" title="map"></a>map</h2><ul>
<li><code>map</code>类似c#中的<code>Dictionary</code>，以<code>key-value</code>对的形式存储数据<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="keyword">var</span> m <span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">string</span>     <span class="comment">//int表示key，string表示value</span></span><br><span class="line">    m = <span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">string</span>&#123;&#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//或者使用make函数</span></span><br><span class="line">    m = <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">string</span>)</span><br><span class="line">    <span class="comment">//或者最简单的</span></span><br><span class="line">    ma := <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">string</span>)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    m := <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">string</span>)</span><br><span class="line">    m[<span class="number">1</span>]=<span class="string">"hello"</span>         <span class="comment">//赋值key为1的map，值为“hello”</span></span><br><span class="line">    <span class="comment">//使用</span></span><br><span class="line">    a := m[<span class="number">1</span>]            <span class="comment">//使用key取值</span></span><br><span class="line">    <span class="comment">//删除</span></span><br><span class="line">    <span class="built_in">delete</span>(m,<span class="number">1</span>)          <span class="comment">//删除key为1的值</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ul>
<li><p>map嵌套的时候，需要对每一级的map进行make操作</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="comment">//声明一个key为int类型，value为map[int]string类型的map</span></span><br><span class="line">    m := <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">string</span>)    </span><br><span class="line">    <span class="comment">//如果直接赋值会报错例如：</span></span><br><span class="line">    m[<span class="number">1</span>][<span class="number">1</span>] = <span class="string">"hello"</span>     <span class="comment">//因为value也是一个map类型，也需要初始化的</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">//正确方式</span></span><br><span class="line">    m[<span class="number">1</span>] = <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">string</span>)</span><br><span class="line">    m[<span class="number">1</span>][<span class="number">1</span>] = <span class="string">"hello"</span></span><br><span class="line">    a := m[<span class="number">1</span>][<span class="number">1</span>]      <span class="comment">//a="hello"</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>判断map是否被初始化</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">     m := <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">string</span>)   </span><br><span class="line">     a, exist = m[<span class="number">2</span>][<span class="number">1</span>]             <span class="comment">//使用多返回值，判断map是否存在(初始化)，返回一个bool类型的值</span></span><br><span class="line">     <span class="keyword">if</span> !exist &#123;</span><br><span class="line">         <span class="comment">//如果不存在，就进行初始化一下</span></span><br><span class="line">         m[<span class="number">2</span>]=<span class="built_in">make</span>(<span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">string</span>)</span><br><span class="line">     &#125;</span><br><span class="line">     a = m[<span class="number">2</span>][<span class="number">1</span>]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>循环map</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="keyword">for</span> k,v:=<span class="keyword">range</span> <span class="keyword">map</span>&#123;</span><br><span class="line">         <span class="comment">//k，v在这里就是key、value</span></span><br><span class="line">         <span class="comment">//k,v在这里都是一个引用，直接赋值操作是不会改变map中元素的原来的值</span></span><br><span class="line">         <span class="comment">//赋值可以使用这种方式</span></span><br><span class="line">         <span class="keyword">map</span>[k] = <span class="string">"hello"</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="comment">//声明一个map类型的slice</span></span><br><span class="line">    smap := <span class="built_in">make</span>([]<span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">string</span>,<span class="number">5</span>)  </span><br><span class="line">    <span class="keyword">for</span> i,v:=<span class="keyword">range</span> smap&#123;</span><br><span class="line">        v = <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">string</span>,<span class="number">2</span>)</span><br><span class="line">        v[<span class="number">1</span>]=<span class="string">"hello"</span></span><br><span class="line">        fmt.Println(v)   <span class="comment">//输出：map[1:hello]</span></span><br><span class="line">    &#125;</span><br><span class="line">    fmt.Println(smap)    <span class="comment">//这里还是一个空的未初始化的slice，因为在for循环中直接给v进行赋值操作，而此处的v只是一个引用，不会对引用本身(smap)进行修改</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="comment">//声明一个map类型的slice</span></span><br><span class="line">    smap := <span class="built_in">make</span>([]<span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">string</span>,<span class="number">5</span>)  </span><br><span class="line">    <span class="comment">//这里我们要改变smap，就只需要索引就行了，把v隐藏掉</span></span><br><span class="line">    <span class="keyword">for</span> i,_:=<span class="keyword">range</span> smap&#123;</span><br><span class="line">        smap[i] = <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">string</span>,<span class="number">2</span>)  <span class="comment">//这里改变的就是smap本身了</span></span><br><span class="line">        smap[<span class="number">1</span>]=<span class="string">"hello"</span></span><br><span class="line">        fmt.Println(smap[i])   <span class="comment">//输出：map[1:hello]</span></span><br><span class="line">    &#125;</span><br><span class="line">    fmt.Println(smap)      <span class="comment">//输出：[map[1:hello],map[1:hello],map[1:hello],map[1:hello],map[1:hello]]</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ul>
<li>map的间接排序<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> (</span><br><span class="line">    <span class="string">"fmt"</span></span><br><span class="line">    <span class="string">"sort"</span></span><br><span class="line">)</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    ma := <span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">string</span>&#123;<span class="number">1</span>:<span class="string">"a"</span>,<span class="number">2</span>:<span class="string">"b"</span>,<span class="number">3</span>:<span class="string">"d"</span>,<span class="number">4</span>:<span class="string">"e"</span>,<span class="number">5</span>:<span class="string">"f"</span>&#125;</span><br><span class="line">    <span class="comment">//声明一个slice，长度是ma的长度</span></span><br><span class="line">    sl := <span class="built_in">make</span>([]<span class="keyword">int</span>,<span class="built_in">len</span>(ma)) </span><br><span class="line">    i := <span class="number">0</span>   <span class="comment">//声明一个计数器</span></span><br><span class="line">    <span class="keyword">for</span> k,_:<span class="keyword">range</span> ma&#123;</span><br><span class="line">        sl[i] = k</span><br><span class="line">        i++</span><br><span class="line">    &#125;</span><br><span class="line">    sort.Ints(s)  <span class="comment">//使用sort包对sl进行升序排列,然后结合ma就可以对map进行简介的排序了</span></span><br><span class="line">    fmt.Println(s)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h2 id="函数"><a href="#函数" class="headerlink" title="函数"></a>函数</h2><ul>
<li><p>Go语言的函数不支持嵌套、重载和默认参数</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//没有参数。没有返回值</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">fa</span><span class="params">()</span></span>&#123;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//有参数，没有返回值</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">fb</span><span class="params">(a <span class="keyword">int</span>,b <span class="keyword">string</span>)</span></span>&#123;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//有参数，有一个返回值</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">fc</span><span class="params">(a <span class="keyword">int</span>,b <span class="keyword">string</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//有参数，有多个返回值</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">fd</span><span class="params">(a <span class="keyword">int</span>,b <span class="keyword">string</span>)</span> <span class="params">(<span class="keyword">int</span>,<span class="keyword">string</span>,<span class="keyword">byte</span>)</span></span>&#123;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//相同类型的参数、返回值可以简写</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">ff</span><span class="params">(a,b,c <span class="keyword">int</span>)</span> <span class="params">(c,d,e <span class="keyword">int</span>)</span></span>&#123;</span><br><span class="line">    <span class="comment">//这种命名返回值参数，相当于已经创建了相应的参数，如果再次创建就会出错</span></span><br><span class="line">    c := <span class="number">10</span>     <span class="comment">//这是不行的，因为返回值是命名返回值</span></span><br><span class="line">    <span class="keyword">return</span> a, b, c</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>不定长变参</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//不定长变参(其实就是相当于传入了一个slice类型)</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">fa</span><span class="params">(a ...<span class="keyword">int</span>)</span></span>&#123;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//当有其他参数时</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">fb</span><span class="params">(b <span class="keyword">string</span>,a ...<span class="keyword">int</span>)</span></span>&#123;</span><br><span class="line">    <span class="comment">//不定长参数必须放在所有参数的最后</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    fa(<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>int、string值类型参数传递</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    a,b := <span class="number">1</span>,<span class="number">2</span></span><br><span class="line">    fa(a,b)</span><br><span class="line">    fmt.Println(a,b)    <span class="comment">//输出1，2 虽然这里对传进来的a,b进行了重新赋值，但是因为传递进来的是值的拷贝，并没有对a,b本身进行修改，所以还是原来的1，2</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">fa</span><span class="params">(a ...<span class="keyword">int</span>)</span></span>&#123;</span><br><span class="line">    a[<span class="number">0</span>] = <span class="number">3</span></span><br><span class="line">    a[<span class="number">1</span>] = <span class="number">4</span></span><br><span class="line">    fmt.Println(a)      <span class="comment">//输出3，4  </span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>slice引用类型作为参数传递，传递的是内存地址的拷贝</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    s := []<span class="keyword">int</span>&#123;<span class="number">1</span>,<span class="number">2</span>&#125;</span><br><span class="line">    fa(s)</span><br><span class="line">    fmt.Println(s)       <span class="comment">//输出的是[3,4] ，因为slice传递的是内存地址的拷贝，改变的是slice本身</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">fa</span><span class="params">(a []<span class="keyword">int</span>)</span></span>&#123;</span><br><span class="line">    a[<span class="number">0</span>] = <span class="number">3</span></span><br><span class="line">    a[<span class="number">1</span>] = <span class="number">4</span></span><br><span class="line">    fmt.Println(a)     <span class="comment">//输出的是[3,4]</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>传递引用类型，使用指针修改参数本身</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    a := <span class="number">1</span></span><br><span class="line">    fa(&amp;a)      <span class="comment">//传递变量a的内存地址</span></span><br><span class="line">    fmt.Println(a)       <span class="comment">//输出：2 ,因为传递的是a变量的内存地址，在fa函数中实际上就是对a本身进行操作了</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//传递一个指针类型</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">fa</span><span class="params">(a *<span class="keyword">int</span>)</span></span>&#123;</span><br><span class="line">    *a = <span class="number">2</span></span><br><span class="line">    fmt.Println(*a)      <span class="comment">//输出：2</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>函数可以作为类型使用</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    a := fa</span><br><span class="line">    a()     <span class="comment">//把函数fa当作类型参数赋值，然后调用</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">fa</span><span class="params">()</span></span>&#123;</span><br><span class="line">    fmt.Println(<span class="string">"hello"</span>)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>匿名函数的使用</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    a := <span class="function"><span class="keyword">func</span> <span class="params">()</span></span>&#123;</span><br><span class="line">        fmt.Println(<span class="string">"hello"</span>)</span><br><span class="line">    &#125;</span><br><span class="line">    a()    <span class="comment">//直接把匿名函数赋值，然后调用</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>闭包</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    f := closure(<span class="number">10</span>)   <span class="comment">//将函数赋值给变量</span></span><br><span class="line">    fmt.Println(f(<span class="number">1</span>))  <span class="comment">//输出11</span></span><br><span class="line">    fmt.Println(f(<span class="number">2</span>))  <span class="comment">//输出12</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//声明一个接受int类型参数，返回值是一个匿名函数的函数</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">closure</span><span class="params">(x <span class="keyword">int</span>)</span> <span class="title">func</span><span class="params">(<span class="keyword">int</span>)</span> <span class="title">int</span></span>&#123;</span><br><span class="line">    <span class="comment">//closure函数的返回值是一个匿名函数，接受一个int参数，返回一个int值</span></span><br><span class="line">    <span class="keyword">return</span> <span class="function"><span class="keyword">func</span><span class="params">(y <span class="keyword">int</span>)</span> <span class="title">int</span></span>&#123;</span><br><span class="line">        <span class="keyword">return</span> x + y</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h3 id="defer"><a href="#defer" class="headerlink" title="defer"></a>defer</h3><ul>
<li><p>类似于其他语言中的析构函数，在函数体执行结束后，按照调用顺序相反的顺序捉个执行一遍</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; <span class="number">3</span>; i++&#123;</span><br><span class="line">        <span class="keyword">defer</span> fmt.Println(i)    <span class="comment">//输出的结果是2，1，0，因为defer是按照调用相反的顺序执行的</span></span><br><span class="line">    &#125; </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>即使函数发生严重的错误，defer也会正常执行</p>
</li>
<li><p>支持匿名函数调用</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; <span class="number">3</span>; i++&#123;</span><br><span class="line">       <span class="keyword">defer</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span>&#123;</span><br><span class="line">            fmt.Println(i)    <span class="comment">//输出3,3,3 因为defer是按照相反的顺序执行的，正常结果应该就是3,2,输出3，3，3是因为在函数里面的i是值的引用，所以在调用的时候拿到的i都是最后一次调用过后的3</span></span><br><span class="line">       &#125;()     <span class="comment">//最后的括号表示调用这个函数，defer可以用来调用函数，这里就相当于赋值变量后 fa() 这样</span></span><br><span class="line">    &#125; </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>Go语言没有异常处理机制，没有c#中<code>try cache</code>语句</p>
</li>
<li>在Go语言中可以使用<code>panic</code>/<code>recover</code>模式来处理错误<ul>
<li><code>panic</code>可以在任何地方引发错误抛出</li>
<li><code>recover</code>只能在<code>defer</code>调用的函数中有效，因为使用<code>recover</code>的时候错误已经引发了，只能借助于<code>defer</code>进行一些“恢复”操作</li>
<li><code>recover</code>可以返回<code>panic</code>信息<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">fa</span><span class="params">()</span></span>&#123;</span><br><span class="line">    fmt.Println(<span class="string">"func fa"</span>)</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">fb</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="comment">//defer如果放在panic 后面，那么就执行不了recover了，因为程序走到panic的时候就已经停止不会往下走了，所以需要在开始就注册recover，在有panic信息抛出，就执行recover</span></span><br><span class="line">    <span class="keyword">defer</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span>&#123;</span><br><span class="line">        <span class="keyword">if</span> err := <span class="built_in">recover</span>(); err != <span class="literal">nil</span>&#123;</span><br><span class="line">            <span class="comment">//获取到了panic信息</span></span><br><span class="line">            fmt.Println(<span class="string">"recover fb"</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">panic</span>(<span class="string">"panic fb"</span>)   <span class="comment">//引发错误</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">fc</span><span class="params">()</span></span>&#123;</span><br><span class="line">    fmt.Println(<span class="string">"func fc"</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//在没有写defer的时候最终输出</span></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">func fa</span></span><br><span class="line"><span class="comment">panic fb</span></span><br><span class="line"><span class="comment">...</span></span><br><span class="line"><span class="comment">other err info</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//在写有defer recover的时候会输出</span></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">func fa</span></span><br><span class="line"><span class="comment">recover fb</span></span><br><span class="line"><span class="comment">func fc</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure>
</li>
</ul>
</li>
</ul>
<h2 id="结构struct"><a href="#结构struct" class="headerlink" title="结构struct"></a>结构struct</h2><ul>
<li>Go语言中没有<code>class</code>的概念，而<code>struct</code>就相当于go语言中的类</li>
<li><p><code>struct</code>是一种类型(type)</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//声明一个名称为person的struct</span></span><br><span class="line"><span class="keyword">type</span> person <span class="keyword">struct</span>&#123;</span><br><span class="line">    Name <span class="keyword">string</span>     <span class="comment">//一个string类型的属性Name</span></span><br><span class="line">    Age <span class="keyword">int</span>         <span class="comment">//一个int类型的属性Age</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="comment">//声明一个person类型的变量</span></span><br><span class="line">    a := person&#123;&#125;</span><br><span class="line">    a.Name = <span class="string">"lisan"</span></span><br><span class="line">    a.Age = <span class="number">11</span></span><br><span class="line">    fmt.Println(a)   <span class="comment">//输出：&#123;lisan 11&#125;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">//常用的形式是，直接初始化</span></span><br><span class="line">    b := person&#123;</span><br><span class="line">        Name : <span class="string">"lisan"</span>,</span><br><span class="line">        Age : <span class="number">11</span></span><br><span class="line">    &#125;</span><br><span class="line">    fmt.Println(b)   <span class="comment">//输出：&#123;lisan 11&#125;</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p><code>struct</code>是一个值类型，传递的时候是值拷贝，在其他函数中修改改变不了值本身，希望做改变的时候，可以使用指针传递</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> person <span class="keyword">struct</span>&#123;</span><br><span class="line">    Name <span class="keyword">string</span></span><br><span class="line">    Age <span class="keyword">int</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="comment">//一般在初始化的时候，直接对struct进行取地址的操作，方便在之后调用的时候，可以拿到地址引用修改struct本身的数值</span></span><br><span class="line">    a := &amp;person&#123;</span><br><span class="line">        Name = <span class="string">"lisan"</span>,</span><br><span class="line">        Age = <span class="number">11</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//调用改变person的Age值的函数</span></span><br><span class="line">    fa(a)</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//因为声明的a是person的内存地址，所以在传入参数的地方使用指针(*)，这样就可以使用内存地址对person进行实际的修改了</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">fa</span><span class="params">(per *person)</span></span>&#123;</span><br><span class="line">    per.Age = <span class="number">20</span></span><br><span class="line">    fmt.Println(per)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>匿名结构</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    a := <span class="keyword">struct</span>&#123;  <span class="comment">//直接声明一个没有名称的struct</span></span><br><span class="line">        Name <span class="keyword">string</span></span><br><span class="line">        Age <span class="keyword">int</span></span><br><span class="line">    &#125;&#123;  <span class="comment">//声明完成后接着执行初始化操作</span></span><br><span class="line">        Name : <span class="string">"lisan"</span>,</span><br><span class="line">        Age : <span class="number">11</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//如果需要传递内存地址,写上&amp;符号就可以了</span></span><br><span class="line">    b := &amp;<span class="keyword">struct</span>&#123;</span><br><span class="line">        Name <span class="keyword">string</span></span><br><span class="line">    &#125;&#123;</span><br><span class="line">        Name = <span class="string">"lisan"</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>嵌套struct</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> person <span class="keyword">struct</span>&#123;</span><br><span class="line">    Name <span class="keyword">string</span></span><br><span class="line">    Age <span class="keyword">int</span></span><br><span class="line">    Contact <span class="keyword">struct</span>&#123;   <span class="comment">//person的Contact属性又是一个struct</span></span><br><span class="line">        Phone, Address <span class="keyword">string</span> </span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    a := person&#123;</span><br><span class="line">        Name : <span class="string">"lisan"</span>,</span><br><span class="line">        Age : <span class="number">11</span></span><br><span class="line">        <span class="comment">//Contact是一个嵌套struct，不能再这么初始化了</span></span><br><span class="line">    &#125;</span><br><span class="line">    a.Contact.Phone = <span class="string">"13233333"</span></span><br><span class="line">    a.Contact.Address = <span class="string">"china"</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>匿名字段</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> person <span class="keyword">struct</span>&#123;</span><br><span class="line">    <span class="keyword">string</span>     <span class="comment">//没有字段名称，只有类型</span></span><br><span class="line">    <span class="keyword">int</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    a := person&#123;</span><br><span class="line">        <span class="string">"lisan"</span>,</span><br><span class="line">        <span class="number">11</span></span><br><span class="line">    &#125;</span><br><span class="line">    fmt.Println(a)</span><br><span class="line"></span><br><span class="line">    <span class="comment">//下面这种初始化会发生错误</span></span><br><span class="line">    b := person&#123;</span><br><span class="line">        <span class="number">11</span>,      <span class="comment">//因为这里使用的是匿名字段，初始化的时候只能根据</span></span><br><span class="line">        <span class="string">"lisan"</span>  <span class="comment">//类型的顺序进行匹配，所以一定要严格按照声明匿名</span></span><br><span class="line">    &#125;            <span class="comment">//struct的字段类型顺序进行初始化</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>相同类型的struct相互之间可以进行赋值</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> person <span class="keyword">struct</span>&#123;</span><br><span class="line">    Name <span class="keyword">string</span></span><br><span class="line">    Age <span class="keyword">int</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    a := person&#123;Name : <span class="string">"lisan"</span>,Age : <span class="number">11</span>&#125;</span><br><span class="line">    <span class="comment">//声明一个person类型的变量b</span></span><br><span class="line">    <span class="keyword">var</span> b person</span><br><span class="line">    <span class="comment">//将a赋值给b的操作是允许的</span></span><br><span class="line">    b = a</span><br><span class="line">    fmt.Println(b)    <span class="comment">//输出的跟a相同</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>两个名称不同的struct，尽管它们的字段一致，它们也是两个不同的类型，它们之间不能进行比较个赋值。</p>
</li>
<li><p>使用嵌入结构实现类似继承的能力</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> person <span class="keyword">struct</span>&#123;</span><br><span class="line">    Sex <span class="keyword">int</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> teacher <span class="keyword">struct</span>&#123;</span><br><span class="line">    person           <span class="comment">//把一个struct当作字段放来</span></span><br><span class="line">    Name <span class="keyword">string</span></span><br><span class="line">    Age <span class="keyword">int</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">type</span> student <span class="keyword">struct</span>&#123;</span><br><span class="line">    person</span><br><span class="line">    Name <span class="keyword">string</span></span><br><span class="line">    Age <span class="keyword">int</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">        <span class="comment">//因为前面说过匿名字段，这里的person相当与一个匿名字段，</span></span><br><span class="line">        <span class="comment">//但是如果直接初始化会报错，这种组合关系，会给person类型一</span></span><br><span class="line">        <span class="comment">//认的名字，和类型相同，这样初始化操作就可以</span></span><br><span class="line">    a := teacher&#123;Name : <span class="string">"zhangsan"</span>,Age : <span class="number">29</span>,person : person&#123;Sex : <span class="number">1</span>&#125;&#125;</span><br><span class="line">    b := student&#123;Name : <span class="string">"lisi"</span>,Age : <span class="number">11</span>,person : person&#123;Sex : <span class="number">0</span>&#125;&#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//调用的时候可以直接使用</span></span><br><span class="line">    a.Sex = <span class="number">1</span></span><br><span class="line">    b.Sex = <span class="number">0</span></span><br><span class="line">    <span class="comment">//也可以这样调用</span></span><br><span class="line">    a.person.Sex = <span class="number">1</span></span><br><span class="line">    b.person.Sex = <span class="number">0</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>嵌入结构，同名字段的处理</p>
<ul>
<li><p>单层嵌套</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> sa <span class="keyword">struct</span>&#123;</span><br><span class="line">    sb</span><br><span class="line">    Name <span class="keyword">string</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">type</span> sb <span class="keyword">struct</span>&#123;</span><br><span class="line">    Name <span class="keyword">string</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    a := sa&#123; Name : <span class="string">"sa"</span>,sb : sb&#123;Name : <span class="string">"sb"</span>&#125;&#125;</span><br><span class="line">    <span class="comment">//a.Name就会找sa中的Namw字段</span></span><br><span class="line">    <span class="comment">//a.sb.Name就会找sb中的Name字段</span></span><br><span class="line">    fmt.Println(a.Name,a.sb.Name)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>多层嵌入</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> sa <span class="keyword">struct</span>&#123;</span><br><span class="line">    sb</span><br><span class="line">    sc</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">type</span> sb <span class="keyword">struct</span>&#123;</span><br><span class="line">    Name <span class="keyword">string</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">type</span> sc <span class="keyword">struct</span>&#123;</span><br><span class="line">    Name <span class="keyword">string</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    a := sa&#123;sb : &#123;Name : <span class="string">"sb"</span>&#125;,sc : &#123;Name : <span class="string">"sc"</span>&#125;&#125;</span><br><span class="line">    fmt.Println(a.Name) <span class="comment">//这里会报错，因为sb、sc里面都有Name字段，没有办法判断该调用哪个,可以使用a.sb.Name 、a.sc.Name</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
</li>
</ul>
<h2 id="方法method"><a href="#方法method" class="headerlink" title="方法method"></a>方法method</h2><ul>
<li><p>相当于是c#中的扩展方法，给某一个类型(type)编写额外的扩展方法，供类型(type)调用</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> sa <span class="keyword">struct</span>&#123;</span><br><span class="line">    Name <span class="keyword">string</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">type</span> sb strut&#123;</span><br><span class="line">    Name <span class="keyword">string</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    a := sa&#123;&#125;</span><br><span class="line">    a.PrintName()   <span class="comment">//因为是给类型sa绑定的方法，所以可以像c#中那样调用</span></span><br><span class="line"></span><br><span class="line">    b := sb&#123;&#125;</span><br><span class="line">    b.PrintName()</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//method</span></span><br><span class="line"><span class="comment">//虽然两个方法都是Print，但是因为传入的参数不同，所以是两个不同的方法</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(a sa)</span> <span class="title">PrintName</span><span class="params">()</span></span>&#123;</span><br><span class="line">    fmt.Println(<span class="string">"sa"</span>)</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(a sb)</span> <span class="title">PrintName</span><span class="params">()</span></span>&#123;</span><br><span class="line">    fmt.Println(<span class="string">"sb"</span>)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>方法同样可以传入指针，对参数本身进行修改</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> sa <span class="keyword">struct</span>&#123;</span><br><span class="line">    Name <span class="keyword">string</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    a := sa&#123;Name:<span class="string">"zhangsan"</span>&#125;</span><br><span class="line">    fmt.Println(a.Name)    <span class="comment">//zhangsan</span></span><br><span class="line">    a.EditName()           <span class="comment">//因为调用这个方法传入的是指针，所以修改了Name本身的值</span></span><br><span class="line">    fmt.Println(a.Name)    <span class="comment">//lisi</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(a *sa)</span> <span class="title">EditName</span><span class="params">()</span></span> &#123;</span><br><span class="line">    a.Name = <span class="string">"lisi"</span></span><br><span class="line">    fmt.Println(a.Name)    <span class="comment">//lisi</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>使用底层类型方法</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> IN <span class="keyword">int</span>  <span class="comment">//声明一个底层为int类型的type</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(i *IN)</span> <span class="title">Add</span><span class="params">(num <span class="keyword">int</span>)</span></span>&#123;</span><br><span class="line">    *i += IN(num)  <span class="comment">//i是IN类型的，num是int类型的，虽然IN底层是int，但是不同的两个类型，所以要进行强制转换</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="keyword">var</span> a IN</span><br><span class="line">    a.Add(<span class="number">100</span>)</span><br><span class="line">    fmt.Println(a)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h2 id="接口interface"><a href="#接口interface" class="headerlink" title="接口interface"></a>接口interface</h2><ul>
<li>接口是一个或多个方法签名的集合(类似c#中的接口，只有声明，没有具体的实现)</li>
<li><p>只要某个类型拥有某个接口的所有的方法签名，那么就算是这个类型实现了该接口，而无需显示的声明实现了哪个接口(在c#中实现一个接口是在类的名字后面写上冒号，然后写接口名，go语言中无需这样做)</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//声明一个接口</span></span><br><span class="line"><span class="keyword">type</span> USB <span class="keyword">interface</span>&#123;</span><br><span class="line">    Name() <span class="keyword">string</span>    <span class="comment">//一个返回string类型的方法Name</span></span><br><span class="line">    Connect()        <span class="comment">//一个没有返回值的方法Connect</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">type</span> PhoneConnect <span class="keyword">struct</span>&#123;</span><br><span class="line">    name <span class="keyword">string</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//结构PhoneConnect实现了接口USB的所有方法，所以就说明结构PhoneConnect实现了接口USB</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(ph PhoneConnect)</span> <span class="title">Name</span><span class="params">()</span> <span class="title">string</span></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> ph.Name    </span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(ph PhoneConnect)</span> <span class="title">Connect</span><span class="params">()</span></span>&#123;</span><br><span class="line">    fmt.Println(<span class="string">"Connected:"</span>,pc.Name)    </span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="keyword">var</span> a USB</span><br><span class="line">    <span class="comment">//a虽然是USB类型的参数，但是由于PhoneConnect实现了USB接口，所以可以给a赋值一个PhoneConnect类型</span></span><br><span class="line">    a = PhoneConnect&#123;name:<span class="string">"PhoneConnect"</span>&#125;</span><br><span class="line">    a.Connect()       <span class="comment">//输出“Connected:PhoneConnect”</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>可以嵌入接口</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//声明一个接口</span></span><br><span class="line"><span class="keyword">type</span> USB <span class="keyword">interface</span>&#123;</span><br><span class="line">    Name() <span class="keyword">string</span>    </span><br><span class="line">    Connecter    <span class="comment">//这里把一个接口嵌入进来</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">type</span> Connecter <span class="keyword">interface</span>&#123;</span><br><span class="line">    Connect()</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">type</span> PhoneConnect <span class="keyword">struct</span>&#123;</span><br><span class="line">    name <span class="keyword">string</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(ph PhoneConnect)</span> <span class="title">Name</span><span class="params">()</span> <span class="title">string</span></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> ph.Name    </span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//Connect方法是嵌入进接口USB的，也是USB接口的声明，需要实现它</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(ph PhoneConnect)</span> <span class="title">Connect</span><span class="params">()</span></span>&#123;</span><br><span class="line">    fmt.Println(<span class="string">"Connected:"</span>,pc.Name)    </span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="keyword">var</span> a USB</span><br><span class="line">    a = PhoneConnect&#123;name:<span class="string">"PhoneConnect"</span>&#125;</span><br><span class="line">    a.Connect()       <span class="comment">//输出“Connected:PhoneConnect”</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>接口调用</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//编写一个判断传入对象的方法</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">Disconnect</span><span class="params">(usb USB)</span></span>&#123;</span><br><span class="line">    <span class="comment">//判断传入这个方法的是不是“PhoneConnect”类型，如果是就执行一些操作</span></span><br><span class="line">    <span class="keyword">if</span> ph,ok := usb.(PhoneConnect); ok&#123;</span><br><span class="line">         <span class="comment">//输出：“Disconnected：PhoneConnect”</span></span><br><span class="line">        fmt.Println(<span class="string">"Disconnected:"</span>,ph.name)  </span><br><span class="line">        <span class="keyword">return</span></span><br><span class="line">    &#125;</span><br><span class="line">    fmt.Println(<span class="string">"No PhoneConnect"</span>)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>所有的类型的父接口，就是一个空的接口(相当于就是c#中的<code>System.Object</code>)，理论上来说所有的类型都实现了一个空接口</p>
</li>
<li><p>简单工厂</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//方法接受一个空接口，也就是可以传入进来任何值</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">Disconnect</span><span class="params">(usb <span class="keyword">interface</span>&#123;&#125;)</span></span>&#123;</span><br><span class="line">    <span class="comment">//根据传入的值的类型，做出不同的操作</span></span><br><span class="line">    <span class="keyword">switch</span> v := usb.(<span class="keyword">type</span>)&#123;   <span class="comment">//这里的type就是让系统判断传入的类型</span></span><br><span class="line">        <span class="keyword">case</span> PhoneConnect:</span><br><span class="line">            fmt.Println(<span class="string">"Disconnected:"</span>,v.name)</span><br><span class="line">        <span class="keyword">default</span>:</span><br><span class="line">            fmt.Println(<span class="string">"No PhoneConnect"</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>接口之间可以互相转换：按照上面的例子，因为接口<code>USB</code>包含了接口<code>Connecter</code>,所以接口<code>USB</code>可以转换成<code>Connecter</code>,但是<code>Connecter</code>不能转换乘<code>USB</code>,这里有一个包含和被包含的关系</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="comment">//a是接口USB变量</span></span><br><span class="line">    a := PhoneConnect&#123;<span class="string">"PhoneConnect"</span>&#125;  </span><br><span class="line">    <span class="keyword">var</span> b Connecter</span><br><span class="line">    b = Connecter(a)    <span class="comment">//Connecter可以转换为USB去执行</span></span><br><span class="line">    a.Connect()    <span class="comment">//输出“Connected:PhoneConnect”</span></span><br><span class="line">    <span class="comment">//但是b中没有USB的Name方法，因为Connecter是被USB包含的，拿不到上一级的成员</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h2 id="反射reflection"><a href="#反射reflection" class="headerlink" title="反射reflection"></a>反射reflection</h2><ul>
<li>反射使用<code>TypeOf</code>和<code>ValueOf</code>函数从接口中获取目标对象信息。<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line">    <span class="string">"fmt"</span></span><br><span class="line">    <span class="string">"reflect"</span>    <span class="comment">//反射包</span></span><br><span class="line">)</span><br><span class="line"><span class="keyword">type</span> User <span class="keyword">struct</span>&#123;</span><br><span class="line">    Id <span class="keyword">int</span></span><br><span class="line">    Name <span class="keyword">string</span></span><br><span class="line">    Age <span class="keyword">int</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(u User)</span> <span class="title">Hello</span><span class="params">()</span></span>&#123;</span><br><span class="line">    fmt.Println(<span class="string">"hello"</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    u := User&#123;<span class="number">1</span>,<span class="string">"OK"</span>,<span class="number">12</span>&#125;</span><br><span class="line">    <span class="comment">//传入结构类型的值u</span></span><br><span class="line">    Info(o)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//传入一个空接口(即可以传入任何类型的参数)</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">Info</span><span class="params">(o <span class="keyword">interface</span>&#123;&#125;)</span></span>&#123;</span><br><span class="line">    <span class="comment">//反射获取参数o的类型信息</span></span><br><span class="line">    t := reflect.TypeOf(o)</span><br><span class="line">    fmt.Println(<span class="string">"Type:"</span>,t.Name())</span><br><span class="line"></span><br><span class="line">    v := reflect.ValueOf(o)</span><br><span class="line">    fmt.Println(<span class="string">"Fields:"</span>)</span><br><span class="line"></span><br><span class="line">    <span class="comment">//获取值信息需要使用循环(因为有多个字段)</span></span><br><span class="line">    <span class="comment">//NumField函数可以获取类型中字段的个数</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>;i &lt; t.NumField(); i++&#123;</span><br><span class="line">        f := t.Field(i)    <span class="comment">//根据字段的索引，获取字段的信息</span></span><br><span class="line">        val := v.Field(i).Interface()  <span class="comment">//取出字段对应的值</span></span><br><span class="line">        fmt.Printf(<span class="string">"%6s: %v = %v\n"</span>,f.Name,f.Type,val)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//获取参数o的方法信息</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; t.NumMethod(); i++&#123;</span><br><span class="line">        m := t.Method(i)</span><br><span class="line">        fmt.Printf(<span class="string">"%6s : %v\n"</span>,m.Name,m.Type)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>输出结果<br><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">Type: User</span><br><span class="line">Fields: </span><br><span class="line">   Id: int = 1</span><br><span class="line"> Name: string = OK</span><br><span class="line">  Age: int = 12</span><br><span class="line">Hello: func(main.User)</span><br></pre></td></tr></table></figure></p>
<ul>
<li>如果传入反射的参数是一个地址引用，那么使用上面的方法就会出错，可以使用if判断一下</li>
</ul>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    u := User&#123;<span class="number">1</span>,<span class="string">"OK"</span>,<span class="number">12</span>&#125;</span><br><span class="line">    Info(&amp;o)</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">Info</span><span class="params">(o Interface&#123;&#125;)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> k := t.Kind(); k != reflect.Struct&#123;</span><br><span class="line">        fmt.Println(<span class="string">"传入的参数不是Sstruct"</span>)</span><br><span class="line">        <span class="keyword">return</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ul>
<li>反射匿名、嵌入字段<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> User <span class="keyword">struct</span>&#123;</span><br><span class="line">    Id <span class="keyword">int</span></span><br><span class="line">    Name <span class="keyword">string</span></span><br><span class="line">    Age <span class="keyword">int</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">type</span> Manager <span class="keyword">struct</span>&#123;</span><br><span class="line">    User    <span class="comment">//匿名字段(结构类型)</span></span><br><span class="line">    title <span class="keyword">string</span> </span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    m := Manager&#123;User:User&#123;<span class="number">1</span>,<span class="string">"OK"</span>,<span class="number">12</span>&#125;,title:<span class="string">"haha"</span>&#125;</span><br><span class="line">    t := reflect.TypeOf(m)</span><br><span class="line"></span><br><span class="line">    <span class="comment">//输出1</span></span><br><span class="line">    fmt.Printf(<span class="string">"%#v\n"</span>,t.Field(<span class="number">0</span>))</span><br><span class="line">    <span class="comment">//输出2</span></span><br><span class="line">    fmt.Printf(<span class="string">"%#v\n"</span>,t.Field(<span class="number">1</span>))</span><br><span class="line"></span><br><span class="line">    <span class="comment">//上面两个取的都是Magager的两个字段，但是匿名字段User中的怎么取呢</span></span><br><span class="line">    <span class="comment">//输出3</span></span><br><span class="line">    fmt.Printf(<span class="string">"%#v\n"</span>,t.FieldByIndex([]<span class="keyword">int</span>&#123;<span class="number">0</span>,<span class="number">0</span>&#125;))</span><br><span class="line">     <span class="comment">//输出4</span></span><br><span class="line">    fmt.Printf(<span class="string">"%#v\n"</span>,t.FieldByIndex([]<span class="keyword">int</span>&#123;<span class="number">0</span>,<span class="number">1</span>&#125;))</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>输出：<br><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">//输出1：可以看到根据索引，输出了第一个字段(匿名字段)的类型信息最后一个参数很特殊：Anonymous，值为true的时候表示这个字段是匿名字段，反之就不是匿名字段</span><br><span class="line">reflect.StructField&#123;Name:"User", PkgPath:"", Type:(*reflect.rtype)(0x4a4000), Tag:"", Offset:0x0, Index:[]int&#123;0&#125;, Anonymous:true&#125;</span><br><span class="line"></span><br><span class="line">输出2：这个也输出了第二个字段的信息，最后一个参数Anonymous值为false，说明这个字段不是匿名字段</span><br><span class="line">reflect.StructField&#123;Name:"title", PkgPath:"main", Type:(*reflect.rtype)(0x4988e0), Tag:"", Offset:0x20, Index:[]int&#123;1&#125;, Anonymous:false&#125;</span><br><span class="line"></span><br><span class="line">//输出3：可以看出来这里取到了User中的Id字段的信息</span><br><span class="line">reflect.StructField&#123;Name:"Id", PkgPath:"", Type:(*reflect.rtype)(0x4982e0), Tag:"", Offset:0x0, Index:[]int&#123;0&#125;, Anonymous:false&#125;</span><br><span class="line"></span><br><span class="line">//输出4：</span><br><span class="line">reflect.StructField&#123;Name:"Name", PkgPath:"", Type:(*reflect.rtype)(0x498860), Tag:"", Offset:0x8, Index:[]int&#123;1&#125;, Anonymous:false&#125;</span><br></pre></td></tr></table></figure></p>
<ul>
<li><p>反射修改字段的值</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    i := <span class="number">111</span></span><br><span class="line">    v := reflect.ValueOf(&amp;i)    <span class="comment">//传入内存地址，获取int类型i的值</span></span><br><span class="line">    <span class="comment">//通过Elem()方法取到实际的对象，然后使用SetInt方法给该变量赋值</span></span><br><span class="line">    v.Elem().SetInt(<span class="number">222</span>)  </span><br><span class="line"></span><br><span class="line">    fmt.Println(i)    <span class="comment">//输出222</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>反射修改struct的字段值</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> User <span class="keyword">struct</span>&#123;</span><br><span class="line">    Id <span class="keyword">int</span></span><br><span class="line">    Name <span class="keyword">string</span></span><br><span class="line">    Age <span class="keyword">int</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    u := User&#123;<span class="number">1</span>,<span class="string">"haha"</span>,<span class="number">12</span>&#125;</span><br><span class="line">    Set(&amp;u)   <span class="comment">//传入指针地址</span></span><br><span class="line">    fmt.Println(u)   <span class="comment">//输出:&#123;1 heiheihei 12&#125;</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">Set</span><span class="params">(o <span class="keyword">interface</span>&#123;&#125;)</span></span>&#123;</span><br><span class="line">    v := reflect.ValueOf(o)</span><br><span class="line"></span><br><span class="line">    <span class="comment">//判断反射的value是不是一个引用地址，并且是不是可以被修改的</span></span><br><span class="line">    <span class="keyword">if</span> v.Kind() == reflect.Ptr &amp;&amp; !v.Elem().CanSet() &#123;</span><br><span class="line">        fmt.Println(<span class="string">"reflect error"</span>)</span><br><span class="line">        <span class="keyword">return</span> </span><br><span class="line">    &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">        v = v.Elem()   <span class="comment">//v定义的是反射出来的value，所以能够赋值一个本身真实的对象</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//修改Name字段的值，如果这里的字段名写错了，那么就无法进行修改</span></span><br><span class="line">    <span class="keyword">if</span> f := v.FieldByName(<span class="string">"Name"</span>); f.Kind() == reflect.String&#123;</span><br><span class="line">        f.SetString(<span class="string">"heiheihei"</span>)</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//也可以进行一个字段是否存在的判断(防止字段名错误)</span></span><br><span class="line">    f := v.FieldByName(<span class="string">"Name1"</span>)</span><br><span class="line">    <span class="keyword">if</span> !f.IsValid()&#123;</span><br><span class="line">        fmt.Println(<span class="string">"没有这个字段啦"</span>)</span><br><span class="line">        <span class="keyword">return</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//判断字段类型是否是string</span></span><br><span class="line">    <span class="keyword">if</span> f.Kind() == reflect.String&#123;</span><br><span class="line">        f.SetString(<span class="string">"yoyoyo"</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>反射调用方法</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> User <span class="keyword">struct</span>&#123;</span><br><span class="line">    Id <span class="keyword">int</span></span><br><span class="line">    Name <span class="keyword">string</span></span><br><span class="line">    Age <span class="keyword">int</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(u User)</span> <span class="title">Hello</span><span class="params">(name <span class="keyword">string</span>)</span></span>&#123;</span><br><span class="line">    fmt.Println(<span class="string">"Hello"</span>,name,<span class="string">" my name is"</span>,u.Name)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    u := User&#123;<span class="number">1</span>,<span class="string">"OK"</span>,<span class="number">12</span>&#125;</span><br><span class="line">    v := reflect.ValueOf(u)</span><br><span class="line">    <span class="comment">//根据方法名获取方法对象(方法写错则会抛出异常)</span></span><br><span class="line">    mv := v.MethodByName(<span class="string">"Hello"</span>)</span><br><span class="line">    <span class="comment">//组织参数(参数必须是一个slice类型)</span></span><br><span class="line">    args := []reflect.Value&#123;reflect.ValueOf(<span class="string">"hai"</span>)&#125;</span><br><span class="line">    <span class="comment">//调用方法</span></span><br><span class="line">    mv.Call(args)</span><br><span class="line"></span><br><span class="line">    <span class="comment">//最终输出：Hello hai my name is OK</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h2 id="并发concurrency"><a href="#并发concurrency" class="headerlink" title="并发concurrency"></a>并发concurrency</h2><ul>
<li>goroutine是由官方实现的超级“线程池”，每个实例只有4-5KB的栈内存占用，由于实现机制而大幅减少的创建和销毁“线程”的开销，是go语言可以实现高并发的根本原因。</li>
<li>并发不是并行：<ul>
<li>并行是直接利用多核处理器实现多个核心同时运行多线程的能力，并行是由处理器的核心数决定的，例如单核处理器就实现不了并行。</li>
<li>并发是由切换时间片来实现的，每个线程执行一段时间，然后来回切换。</li>
<li>Go语言可以设置使用并发的核数，可以最大发挥多核处理器的能力。</li>
<li>所以Go语言的并发比并行更加高效</li>
</ul>
</li>
<li>goroutine奉行通过通信来共享内存，而不是共享内存来通信<ul>
<li>简单理解：goroutine之间是使用channel进行通信的，而不是使用锁机制，所以不需要对两个goroutine之间的切换加锁，只需要使用go语言实现的channel进行通信即可实现共享内存的切换。</li>
</ul>
</li>
<li>使用<code>go</code>关键字使用：<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span>(</span><br><span class="line">    <span class="string">"fmt"</span></span><br><span class="line">)</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="keyword">go</span> Go()    <span class="comment">//使用gorountine调用Go函数</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">Go</span><span class="params">()</span></span>&#123;</span><br><span class="line">    fmt.Println(<span class="string">"hahaha"</span>)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>上面的代码运行结果并没有跟想象的那样输出一句”hahaha”，而是什么都没有输出，然后就退出了，原因是：我们在main函数中启动了一个goroutine执行Go函数，这时候就由一个线程去执行Go函数了，然后main没什么影响，继续往下执行，下面什么都没有，所以就直接退出了。<br><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//为了正确输出，我们使用线程休眠的方法，实现一下</span></span><br><span class="line"><span class="keyword">import</span>(</span><br><span class="line">    <span class="string">"fmt"</span></span><br><span class="line">    <span class="string">"time"</span></span><br><span class="line">)</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="keyword">go</span> Go()</span><br><span class="line">    time.Sleep(<span class="number">2</span>*time.Second)   <span class="comment">//让线程睡两秒钟，大概可以等到Go函数运行结束，然后再退出main函数</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">Go</span><span class="params">()</span></span>&#123;</span><br><span class="line">    fmt.Prinltn(<span class="string">"hahaha"</span>)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<ul>
<li><p>在实际的代码中，我们一般使用channel进行通信，通知其他函数，这个goroutine执行完毕了，然后可以操作其他的了</p>
<ul>
<li>channel是goroutine之间通信的桥梁，大都是阻塞同步的</li>
<li><p>channel存取值操作：</p>
<ul>
<li>存值使用操作符：<code>channel&lt;-</code> (存值时操作符在channel变量的右边)</li>
<li>取值使用操作符：<code>&lt;-channel</code> (取值时操作符在channel变量的左边)<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    c := <span class="built_in">make</span>(<span class="keyword">chan</span> <span class="keyword">bool</span>)   <span class="comment">//使用make函数创建一个channel，存储bool 类型的值</span></span><br><span class="line">    <span class="comment">//定义一个goroutine匿名函数</span></span><br><span class="line">    <span class="keyword">go</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span>&#123;</span><br><span class="line">        fmt.Println(<span class="string">"hahaha"</span>)</span><br><span class="line">        c &lt;- <span class="literal">true</span>     <span class="comment">//给channel存一个值</span></span><br><span class="line">    &#125;()</span><br><span class="line">    <span class="comment">//在main函数的最后，从channel中取值，所以这里就会等待goroutine中对channel进行存值，然后这里取出来了，才会结束main函数，这里相当一个阻塞线程的操作</span></span><br><span class="line">    &lt;- c</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
</li>
<li><p>channel是通过<code>make()</code>创建，<code>close()</code>进行关闭的</p>
</li>
<li>channel是引用类型</li>
<li><p>可以使用<code>for range</code>来不断的迭代操作channel，进行取值操作</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    c := <span class="built_in">make</span>(<span class="keyword">chan</span> <span class="keyword">bool</span>)</span><br><span class="line">    <span class="keyword">go</span> <span class="function"><span class="keyword">func</span> <span class="params">()</span></span>&#123;</span><br><span class="line">        fmt.Println(<span class="string">"hahaha"</span>)</span><br><span class="line">        c &lt;- <span class="literal">true</span></span><br><span class="line">        Close(s)  <span class="comment">//因为main函数最后有一个for循环在一直迭代取值channel存入的值，所以这里如果不进行Close的话，那么就会发生一个死锁，而抛出异常</span></span><br><span class="line">    &#125;()</span><br><span class="line">    <span class="comment">//这里会等待上面的匿名函数给channel存入一个值，然后打印出来，接着匿名函数调用了Close函数，通知for循环channel关闭，停止迭代，然后main函数继续往下执行，直至退出</span></span><br><span class="line">    <span class="keyword">for</span> _,v := <span class="keyword">range</span> c&#123;</span><br><span class="line">        fmt.Println(v)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>可以设置双向(读写)和单向通道(只读、只写)</p>
</li>
<li>可以设置缓存(channel存储数据量)的大小，在没有到最大值的时候，不会发生线程阻塞<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span> <span class="params">()</span></span>&#123;</span><br><span class="line">    c := <span class="built_in">make</span>(<span class="keyword">chan</span> <span class="keyword">bool</span>,<span class="number">3</span>)   <span class="comment">//创建一个channel，可以存储3个长度的数据</span></span><br><span class="line">    <span class="keyword">go</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span>&#123;</span><br><span class="line">        fmt.Println(<span class="string">"123"</span>)</span><br><span class="line">        c &lt;- <span class="literal">true</span></span><br><span class="line">    &#125;</span><br><span class="line">    &lt;- c   <span class="comment">//取出channel中的数据</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
</li>
</ul>
<blockquote>
</blockquote>
<pre><code>1. 有缓存的channel相当于是非阻塞的，而有进程的是同步阻塞的。
2. channel相当于是queue的功能，先进先出。  
　　如果创建了一个带缓存的channel，那么在channel还没有存储满的时候，取channel数据这个操作不会阻塞程序的运行。反之就会等待channel中有值可以取出时，才会继续下面的其他操作。
　　看到网上一个解释：把channel比作邮递员，有缓存时，相当于你家门外面有一个信箱，只要没装满，邮递员就直接把信放进去就走，不用管你取不取。 没缓存就是邮递员必须把信交到你手里才能走。
</code></pre>
      
    </div>
    <footer class="entry-meta entry-footer">
      
	<span class="ico-folder"></span>
    <a class="article-category-link" href="/categories/Golang/">Golang</a>

      
  <span class="ico-tags"></span>
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Golang入门/">Golang入门</a></li></ul>

      
        <div id="donation_div"></div>

<script src="/js/vdonate.js"></script>
<script>
var a = new Donate({
  title: '如果觉得我的文章对您有用，请随意打赏。您的支持将鼓励我继续创作!', // 可选参数，打赏标题
  btnText: 'Donate', // 可选参数，打赏按钮文字
  el: document.getElementById('donation_div'),
  wechatImage: '/css/images/wechatPay.png',
  alipayImage: '/css/images/alipay.jpg'
});
</script>
      

      
        
	<section id="comments" class="comment">
	  <div id="disqus_thread">
	  <noscript>Please enable JavaScript to view the <a href="//disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
	  </div>
	</section>

	<script type="text/javascript">
	var disqus_shortname = 'haijdblog';
	(function(){
	  var dsq = document.createElement('script');
	  dsq.type = 'text/javascript';
	  dsq.async = true;
	  dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
	  (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
	}());
	(function(){
	  var dsq = document.createElement('script');
	  dsq.type = 'text/javascript';
	  dsq.async = true;
	  dsq.src = '//' + disqus_shortname + '.disqus.com/count.js';
	  (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
	}());
	</script>


      
    </footer>
  </div>
  
    
<nav id="article-nav">
  
    <a href="/2017/08/23/Go标准库-fmt/" id="article-nav-newer" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Newer</strong>
      <div class="article-nav-title">
        
          Go语言标准库-fmt
        
      </div>
    </a>
  
  
    <a href="/2017/08/09/Go命令操作工具/" id="article-nav-older" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Older</strong>
      <div class="article-nav-title">Go命令操作工具</div>
    </a>
  
</nav>

  
</article>

<!-- Table of Contents -->

  <aside id="sidebar">
    <div id="toc" class="toc-article">
    <strong class="toc-title">Contents</strong>
    
      <ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#基础知识"><span class="nav-number">1.</span> <span class="nav-text">基础知识</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#类型与变量"><span class="nav-number">2.</span> <span class="nav-text">类型与变量</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#基本类型"><span class="nav-number">2.1.</span> <span class="nav-text">基本类型</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#类型默认值"><span class="nav-number">2.2.</span> <span class="nav-text">类型默认值</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#类型的别名"><span class="nav-number">2.2.1.</span> <span class="nav-text">类型的别名</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#变量的声明与赋值"><span class="nav-number">2.3.</span> <span class="nav-text">变量的声明与赋值</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#变量的类型转换"><span class="nav-number">2.4.</span> <span class="nav-text">变量的类型转换</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#常量的定义"><span class="nav-number">2.5.</span> <span class="nav-text">常量的定义</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#运算符"><span class="nav-number">2.6.</span> <span class="nav-text">运算符</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#控制语句"><span class="nav-number">2.7.</span> <span class="nav-text">控制语句</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#循环"><span class="nav-number">2.7.1.</span> <span class="nav-text">循环</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#switch"><span class="nav-number">2.7.2.</span> <span class="nav-text">switch</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Array"><span class="nav-number">2.8.</span> <span class="nav-text">Array</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#切片Slice"><span class="nav-number">2.9.</span> <span class="nav-text">切片Slice</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#map"><span class="nav-number">2.10.</span> <span class="nav-text">map</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#函数"><span class="nav-number">2.11.</span> <span class="nav-text">函数</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#defer"><span class="nav-number">2.11.1.</span> <span class="nav-text">defer</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#结构struct"><span class="nav-number">2.12.</span> <span class="nav-text">结构struct</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#方法method"><span class="nav-number">2.13.</span> <span class="nav-text">方法method</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#接口interface"><span class="nav-number">2.14.</span> <span class="nav-text">接口interface</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#反射reflection"><span class="nav-number">2.15.</span> <span class="nav-text">反射reflection</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#并发concurrency"><span class="nav-number">2.16.</span> <span class="nav-text">并发concurrency</span></a></li></ol></li></ol>
    
    </div>
  </aside>
</section>
        
      </div>
      <footer id="footer" class="site-footer">
  

  <div class="clearfix container">
      <div class="site-info">
	      &copy; 2018 haijd All Rights Reserved.
          
            <span id="busuanzi_container_site_uv">
              本站访客数<span id="busuanzi_value_site_uv"></span>人次  
              本站总访问量<span id="busuanzi_value_site_pv"></span>次
            </span>
          
      </div>
      <div class="site-credit">
        Theme by <a href="https://github.com/iTimeTraveler/hexo-theme-hiero" target="_blank">hiero</a>
      </div>
  </div>
</footer>


<!-- min height -->

<script>
    var contentdiv = document.getElementById("content");

    contentdiv.style.minHeight = document.body.offsetHeight - document.getElementById("allheader").offsetHeight - document.getElementById("footer").offsetHeight + "px";
</script>
    </div>
    <!-- <nav id="mobile-nav">
  
    <a href="/" class="mobile-nav-link">Home</a>
  
    <a href="/archives" class="mobile-nav-link">Archives</a>
  
    <a href="/categories" class="mobile-nav-link">Categories</a>
  
    <a href="/tags" class="mobile-nav-link">Tags</a>
  
    <a href="/about" class="mobile-nav-link">About</a>
  
</nav> -->
    

<!-- mathjax config similar to math.stackexchange -->

<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    tex2jax: {
      inlineMath: [ ['$','$'], ["\\(","\\)"] ],
      processEscapes: true
    }
  });
</script>

<script type="text/x-mathjax-config">
    MathJax.Hub.Config({
      tex2jax: {
        skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
      }
    });
</script>

<script type="text/x-mathjax-config">
    MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax(), i;
        for(i=0; i < all.length; i += 1) {
            all[i].SourceElement().parentNode.className += ' has-jax';
        }
    });
</script>

<script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>


  <link rel="stylesheet" href="/fancybox/jquery.fancybox.css">
  <script src="/fancybox/jquery.fancybox.pack.js"></script>


<script src="/js/scripts.js"></script>
<script src="/js/bootstrap.js"></script>
<script src="/js/main.js"></script>








	<script async src="//dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js">
	</script>






  </div>

  <a id="rocket" href="#top" class=""></a>
  <script type="text/javascript" src="/js/totop.js" async=""></script>
</body>
</html>
